package com.example.tvapp;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.*;
import android.view.View;
import android.webkit.*;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.example.tvapp.URL_REGULARS.URL_RULES;
import com.yanzhenjie.andserver.AndServer;
import com.yanzhenjie.andserver.Server;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity
{
    WebView webView=null;
    MainActivity context=this;
    //AndServer服务
    Server server=null;
    private ProgressBar progressBar=null;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what){
                case 1:Toast.makeText(MainActivity.this,"未授予文件读写权限",Toast.LENGTH_LONG).show();break;
                case 2:
                    Toast.makeText(MainActivity.this,"AndServer服务器异常",Toast.LENGTH_LONG).show();break;
                case 3:
                    Toast.makeText(MainActivity.this,"拦截页面跳转失败",Toast.LENGTH_LONG).show();break;
                case 4:
                    Toast.makeText(MainActivity.this,"初始化目录失败",Toast.LENGTH_LONG).show();break;
                default:break;
            }
        }

    };
    private boolean isFullScreen;

    private LinearLayout fullscreenContainer;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fullscreenContainer=findViewById(R.id.fullscreen_container);
        getSupportActionBar().hide();//隐藏自带标题栏
        //AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        //隐藏顶部状态栏，底部导航栏
        getWindow().setStatusBarColor(Color.TRANSPARENT);
        View decorView = getWindow().getDecorView();
        //隐藏状态栏和导航栏
       // 配置全屏模式的系统UI可见性标志
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION // 隐藏底部导航栏
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN // 内容延伸到状态栏下方
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // 完全隐藏导航栏
                | View.SYSTEM_UI_FLAG_FULLSCREEN // 完全隐藏状态栏
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; // 全屏模式下，短暂触摸屏幕后自动隐藏系统UI

        // 应用全屏模式
        decorView.setSystemUiVisibility(uiOptions);

        //decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

        //请求文件读写权限，地三个参数为请求码，用于区分是在哪里发起的请求
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 222);


    }

    //当申请文件读写权限后回调
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        int hasPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        System.out.println("请求权限结果："+hasPermission);
        if(hasPermission==-1)
        {
            //用户拒绝授予权限
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    Message message=new Message();
                    message.what=1;
                    handler.sendMessage(message);
                }
            }).start();

        }
        else//授予权限
        {
            progressBar = findViewById(R.id.progressBar);
            // Toast.makeText(this,Environment.getExternalStorageDirectory().getAbsolutePath(),Toast.LENGTH_LONG).show();
            try
            {
                URL_RULES.initDir(this);
            }
            catch (IOException e)
            {
                e.printStackTrace();
                //用户拒绝授予权限
                new Thread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Message message=new Message();
                        message.what=4;
                        handler.sendMessage(message);
                    }
                }).start();
            }
            //new BookInfoTable().deleteTable();
            //new BookInfoTable().creatBookInfoTable();
            switch (requestCode)
            {
                case 222:
                    // Toast.makeText(getApplicationContext(), "已申请权限", Toast.LENGTH_SHORT).show();
                    //构建服务
                    if(server==null)
                        server = AndServer.webServer(this).port(8080).timeout(10, TimeUnit.SECONDS).listener(new Server.ServerListener()
                        {
                            @Override
                            public void onStarted()
                            {
                                System.out.println("服务启动");
                            }

                            @Override
                            public void onStopped()
                            {
                                System.out.println("服务停止");
                            }

                            @Override
                            public void onException(Exception e)
                            {
                                progressBar.setVisibility(View.GONE);
                                new Thread(new Runnable()
                                {
                                    @Override
                                    public void run()
                                    {
                                        Message message = new Message();
                                        message.what = 2;
                                        handler.sendMessage(message);
                                    }
                                }).start();
                                System.out.println("服务异常");
                            }
                        }).build();
                    //启动服务
                    if(server!=null&&!server.isRunning())
                        server.startup();
                    initWebView();
                    //防止服务器还没启动就访问
                    while (server == null || !server.isRunning()) ;
                {
                    progressBar.setVisibility(View.GONE);
                    webView.loadUrl("http://localhost:8080/index");
                }
                default:
                    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }

        }


    }


    //重写返回按钮，防止直接退出activity
    //可以把所有url按照先后顺序放入一个List<String>做成一个返回栈,便于管理
    @Override
    public void onBackPressed()
    {
        if(webView.getUrl().equals("http://localhost:8080/index"))
        {
            super.onBackPressed();
        }
        else if(webView.canGoBack())
        {
                webView.goBack();
                webView.removeAllViews();
        }
        else
                super.onBackPressed();
    }


    /*用于确保视频横竖屏均可播放视频*/
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        if (isFullScreen) {
            // 当前处于全屏模式，处理屏幕方向变化
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                // 横屏全屏模式
                fullscreenContainer.setOrientation(LinearLayout.HORIZONTAL);
            } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                // 竖屏全屏模式
                fullscreenContainer.setOrientation(LinearLayout.VERTICAL);
            }
        }
    }
    private void initWebView()
    {
        //初始化控件
        webView=findViewById(R.id.wv_webview);
        //访问网页,防止打开系统浏览器
        webView.setWebViewClient(new WebViewClient(){
            //系统默认会通过手机浏览器打开网页，为了能够直接通过WebView显示网页，则必须设置
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {//这个函数当发生从一个页面跳转到另一个页面时被调用,其中的url指另一个页面的url
                String url=String.valueOf(request.getUrl());
                System.out.println("尝试"+url);
                if(!webView.getOriginalUrl().contains("http://localhost:8080")&& !url.equals("http://localhost:8080/index"))
                {
                    try
                    {
                        // System.out.println(webView.getOriginalUrl());
                        URL originUrl = new URL(webView.getOriginalUrl());
                        URL toUrl = new URL(String.valueOf(request.getUrl()));
                        if (!Objects.equals(originUrl.getHost(), toUrl.getHost()))
                            //禁止跳//转到任何与当前视频网站域名不同的任何其他网站
                            return true;//我不太理解这个函数，返回true表示的是拦截页面，不进行跳转
                    }catch (Exception e)
                    {
                        e.printStackTrace();
                        new Thread(new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                Message message = new Message();
                                message.what = 3;
                                handler.sendMessage(message);
                            }
                        }).start();
                        System.out.println("拦截页面跳转失败");
                    }
                }
                if(url.startsWith("http")||url.startsWith("https"))
                {
                    //使用http或https协议的网站比如https://www.bilibili.com
                    view.loadUrl(url);
                    return true;
                }else
                {
                    //使用一些乱七八糟的协议的网站，比如bilibili://www.ahahdias.com
                    //下面是主流的解决方法：就是调用哔哩哔哩APP，但实际上就是在欺负手机端用户，完全没必要调用app
                    // Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    // context.startActivity(intent);
                    return true;
                }

            }
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)//这个函数当一个页面请求其他网络资源时被调用，其中的url指其他资源的url
            {
                String url = request.getUrl().toString();
               // System.out.println("请求资源："+url);
                try
                {
                    ArrayList<String[]> rules=URL_RULES.getRULES();
                    for(int i=0;i<rules.size();i++)
                    {
                       // System.out.println("规则："+rules.get(i)[0]);
                        if(url.contains(rules.get(i)[0]))
                        {
                            try
                            {
                                URL_RULES.addLog(" 拦截请求："+url+"匹配到规则："+rules.get(i)[0]);
                            }
                            catch (IOException e)
                            {
                                e.printStackTrace();
                            }
                            //System.out.println(url+":匹配到规则："+rules.get(i)[0]);
                            //拦截广告资源
                            return new WebResourceResponse(null, null, null);
                        }
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        // 现在在主线程上安全地获取当前 URL
                        // 在这里执行需要用到 currentUrl 的逻辑...
                        try
                        {
                            URL originUrl = new URL(view.getUrl());
                            URL toUrl = new URL(String.valueOf(url));
                            if (!Objects.equals(originUrl.getHost(), toUrl.getHost()))//只记录与本站域名不同的请求
                            {
                                if(!url.toLowerCase().endsWith(".ts")&&!url.toLowerCase().endsWith(".m3u8"))
                                    URL_RULES.addLog(" 请求资源：" + url);
                            }
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                });



                // 对非广告资源，按原计划加载
                return super.shouldInterceptRequest(view, request);
            }

            @Override
            public void onPageFinished(WebView view, String url)
            {
                super.onPageFinished(view, url);
                //千万注意father元素的z-index,越大越好，否则若将悬浮球拖动到一个z-index比起大的元素上，就没办法拖动它了
                if(!url.contains("http://localhost:8080"))
                {
                    String js =" (function () {\n" + "\n" + "        try {\n" + "            showPopup_collect()\n" + "            showPopup_return()\n" + "        } catch (e) {\n" + "        }\n" + "        function showPopup_collect() {\n" + "            let f=document.querySelector(\".father_huangweimin\")\n" + "            if(f!=null)\n" + "            {\n" + "                f.parentNode.removeChild(f)\n" + "            }\n" + "            let father = document.createElement(\"div\")\n" + "            father.className=\"father_huangweimin\"\n" + "            father.style.width = \"50px\"\n" + "            father.style.height = \"50px\"\n" + "            father.style.borderRadius = \"25px\"\n" + "            father.style.display = \"flex\"\n" + "            father.style.justifyContent = \"center\"\n" + "            father.style.alignItems = \"center\"\n" + "            father.style.border = \"1px solid black\"\n" + "            father.style.position = \"absolute\"//!用于实现拖拽移动\n" + "            father.style.zIndex = \"2247483646\"\n" + "\n" + "            father.style.top = \"20px\"\n" + "            father.style.left = 20 + Math.random() * 100 + \"px\"\n" + "            father.style.backgroundColor=\"rgba(1,1,1,0.16)\"\n" + "            let content = document.createElement(\"div\")\n" + "            content.className=\"content_huangweimin\"\n" + "            content.innerHTML = \"<div style='font-size: 11px;text-align: center;color: red'>收藏页面</div>\"\n" + "            content.style.width = \"100%\"\n" + "            content.style.height = \"100%\"\n" + "            content.style.borderRadius = \"50%\"\n" + "            content.style.display = \"flex\"\n" + "            content.style.justifyContent = \"center\"\n" + "            content.style.alignItems = \"center\"\n" + "\n" + "            father.appendChild(content)\n" + "\n" + "            document.body.appendChild(father)\n" + "            content.addEventListener(\"selectstart\",function (e) {\n" + "               e.preventDefault()\n" + "            })\n" + "            content.addEventListener(\"click\",function (e) {\n" + "                let url=window.location.href\n" + "                let 标题=window.prompt(\"请输入标题\")\n" + "                if(标题!=null)\n" + "                {\n" + "                    let 备注=window.prompt(\"请输入备注\")\n" + "                    uploadCollect.callback(url,标题,备注)//使用网络请求的方式上传数据会出现跨域错误\n" + "                }\n" + "            })\n" + "            dragAndDropForPhone(content, father)\n" + "        }\n" + "        function showPopup_return() {\n" + "            let f=document.querySelector(\".father_huangweimin_return\")\n" + "            if(f!=null)\n" + "            {\n" + "                f.parentNode.removeChild(f)\n" + "            }\n" + "            let father = document.createElement(\"div\")\n" + "            father.className=\"father_huangweimin_return\"\n" + "            father.style.width = \"50px\"\n" + "            father.style.height = \"50px\"\n" + "            father.style.borderRadius = \"25px\"\n" + "            father.style.display = \"flex\"\n" + "            father.style.justifyContent = \"center\"\n" + "            father.style.alignItems = \"center\"\n" + "            father.style.border = \"1px solid black\"\n" + "            father.style.position = \"absolute\"//!用于实现拖拽移动\n" + "            father.style.zIndex = \"2247483646\"\n" + "\n" + "            father.style.top = \"60px\"\n" + "            father.style.left = 20 + Math.random() * 100 + \"px\"\n" + "            father.style.backgroundColor=\"rgba(1,1,1,0.16)\"\n" + "            let content = document.createElement(\"div\")\n" + "            content.className=\"content_huangweimin_return\"\n" + "            content.innerHTML = \"<div style='font-size: 11px;text-align: center;color: red'>回到主页</div>\"\n" + "            content.style.width = \"100%\"\n" + "            content.style.height = \"100%\"\n" + "            content.style.borderRadius = \"50%\"\n" + "            content.style.display = \"flex\"\n" + "            content.style.justifyContent = \"center\"\n" + "            content.style.alignItems = \"center\"\n" + "\n" + "            father.appendChild(content)\n" + "\n" + "            document.body.appendChild(father)\n" + "            content.addEventListener(\"selectstart\",function (e) {\n" + "                e.preventDefault()\n" + "            })\n" + "            content.addEventListener(\"click\",function (e) {\n" + "               window.location.href=\"http://localhost:8080/index\"\n" + "            })\n" + "            dragAndDropForPhone(content, father)\n" + "        }\n" + "        function dragAndDropForPhone(e, parent) {\n" + "            var startX = 0; // 获取手指初始坐标\n" + "            var startY = 0;\n" + "            var x = 0; // 获得盒子原来的位置\n" + "            var y = 0;\n" + "            // 手指触摸\n" + "            e.addEventListener('touchstart', function (e) {\n" + "                //  获取手指初始坐标\n" + "                startX = e.targetTouches[0].pageX;\n" + "                startY = e.targetTouches[0].pageY;\n" + "                //x = this.offsetLeft;\n" + "                //y = this.offsetTop;\n" + "                x = parent.offsetLeft\n" + "                y = parent.offsetTop;\n" + "                //this.style.boxShadow = '0 0 15px rgba(0, 0, 0, .6)';\n" + "                parent.style.boxShadow = '0 0 15px rgba(0, 0, 0, .6)';\n" + "            });\n" + "            // 手指离开\n" + "            e.addEventListener('touchend', function (e) {\n" + "                //this.style.boxShadow = '';\n" + "                parent.style.boxShadow = '';\n" + "\n" + "            });\n" + "\n" + "            // 手指按住移动\n" + "            e.addEventListener('touchmove', function (e) {\n" + "                //  计算手指的移动距离：手指移动之后的坐标减去手指初始的坐标\n" + "                var moveX = e.targetTouches[0].pageX - startX;\n" + "                var moveY = e.targetTouches[0].pageY - startY;\n" + "                // 移动盒子 盒子原来的位置 + 手指移动的距离\n" + "                parent.style.left = x + moveX + 'px';\n" + "                parent.style.top = y + moveY + 'px';\n" + "                e.preventDefault(); // 阻止屏幕滚动的默认行为\n" + "            });\n" + "\n" + "        }\n" + "    })()";



                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                    {  //android系统4.4以上的时候调用js方法用这个
                        webView.evaluateJavascript("javascript:" + js, null);

                    }
                    else
                    {
                        webView.loadUrl("javascript:" + js);
                    }
                }
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon)
            {
                super.onPageStarted(view, url, favicon);
            }


        });
        //支持js的Alert(),加载时显示进度条,上传文件等
        webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this);
                b.setTitle("Alert");
                b.setMessage(message);
                b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                    }
                });
                b.setCancelable(false);
                b.create().show();
                return true;
            }
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                // TODO 自动生成的方法存根
                ProgressBar pg1=findViewById(R.id.progressBar1);
                if(newProgress==100){
                    pg1.setVisibility(View.GONE);//加载完网页进度条消失
                    //加载完毕之后在显示，用于解决刚打开app是一闪而过一个白色的东西
                    webView.setVisibility(View.VISIBLE);
                }
                else{
                    pg1.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
                    pg1.setProgress(newProgress);//设置进度值
                }

            }
            // 其他可能需要的方法，如onProgressChanged、onJsAlert等...


            /*下面的代码用于实现全屏播放视频，实现来在AI*/
            private View videoView;

            @Override
            public void onShowCustomView(View view, CustomViewCallback callback) {
                try
                {
                    handleVideoView(view, callback, true);
                }catch (Exception e)
                {
                    System.out.println("出错");
                    e.printStackTrace();
                }
            }

            @Override
            public void onHideCustomView() {
                handleVideoView(null, null, false);
            }

            private void handleVideoView(View view, CustomViewCallback callback, boolean show) {
                if (show) {
                    // 视频进入全屏模式
                    if (videoView != null) {
                        // 如果已有视频处于全屏状态，先退出当前全屏
                        callback.onCustomViewHidden();
                        return;
                    }

                    // 保存新视频视图，并将其添加到全屏容器中
                    videoView = view;
                    fullscreenContainer.addView(videoView);
                    fullscreenContainer.setVisibility(View.VISIBLE);

                    // 隐藏原WebView，进入全屏模式
                    webView.setVisibility(View.GONE);
                } else {
                    // 视频退出全屏模式
                    if (videoView == null) {
                        // 如果当前没有视频处于全屏状态，无需执行任何操作
                        return;
                    }

                    // 将全屏视图移除，恢复原WebView可见
                    fullscreenContainer.removeView(videoView);
                    fullscreenContainer.setVisibility(View.GONE);
                    videoView = null;

                    webView.setVisibility(View.VISIBLE);

                    // 调用回调通知系统全屏模式已结束
                    if (callback != null) {
                        callback.onCustomViewHidden();
                    }
                }
            }





        });

        //激活WebView为活跃态，能正常执行网页的响应
        webView.onResume();
        //是否可以后退、前进
        webView.canGoBack();
        webView.canGoForward();
        //webView.setBackgroundColor(0);
        //webView.getBackground().setAlpha(0);

        WebSettings webSettings= webView.getSettings();
        webSettings.setJavaScriptEnabled(true);//允许与js交互
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);//支持通过js打开新窗口
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        //下面一些设置不是很清楚
        webSettings.setAllowFileAccess(true);
        webSettings.setAllowFileAccessFromFileURLs(true);
        webSettings.setAllowContentAccess(true);
        webSettings.setAllowUniversalAccessFromFileURLs(true);
        webSettings.setAllowFileAccessFromFileURLs(true);

//        webSettings.setBuiltInZoomControls(true);
        webSettings.setGeolocationEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setUseWideViewPort(true); // 关键点
        webSettings.setAllowFileAccess(true); // 允许访问文件
        webSettings.setSupportZoom(true); // 支持缩放
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setPluginState(WebSettings.PluginState.ON);
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//允许网页和网页资源混用Https和Http

        webSettings.setDomStorageEnabled(true);//这个属性与某些网站的视频能否播放有关。http://www.xigua60.com/play/116826-1-0.html
    }

}